ํ์ ์คํฌ๋ฆฝํธ์ ์ดํํธ ํ์ ์ ํ์ฉํด ์ฌ์ด๋ ์ดํํธ๋ฅผ ์ถ์ ํ์ฌ, ๋ ์์ธก ๊ฐ๋ฅํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ํ๊ตฌํฉ๋๋ค.
ํ์ ์คํฌ๋ฆฝํธ ์ดํํธ ํ์ : ์ฌ์ด๋ ์ดํํธ ์ถ์ ์ ์ํ ์ค์ฉ ๊ฐ์ด๋
ํ๋ ์ํํธ์จ์ด ๊ฐ๋ฐ์์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ ๊ฒฌ๊ณ ํ๊ณ ์์ธก ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ ์ญ ์ํ ์์ , I/O ์์ ์ํ, ์์ธ ๋ฐ์๊ณผ ๊ฐ์ ์ฌ์ด๋ ์ดํํธ๋ ๋ณต์ก์ฑ์ ์ผ๊ธฐํ๊ณ ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. ํ์ ์คํฌ๋ฆฝํธ๋ ํ์ค์ผ(Haskell)์ด๋ ํจ์ด์คํฌ๋ฆฝํธ(PureScript)์ ๊ฐ์ ์์ ํจ์ํ ์ธ์ด์ฒ๋ผ ์ ์ฉ "์ดํํธ ํ์ "์ ๋ค์ดํฐ๋ธ๋ก ์ง์ํ์ง๋ ์์ง๋ง, ํ์ ์คํฌ๋ฆฝํธ์ ๊ฐ๋ ฅํ ํ์ ์์คํ ๊ณผ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์์น์ ํ์ฉํ์ฌ ํจ๊ณผ์ ์ธ ์ฌ์ด๋ ์ดํํธ ์ถ์ ์ ๋ฌ์ฑํ ์ ์์ต๋๋ค. ์ด ๊ธ์์๋ ํ์ ์คํฌ๋ฆฝํธ ํ๋ก์ ํธ์์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๊ด๋ฆฌํ๊ณ ์ถ์ ํ๋ ๋ค์ํ ์ ๊ทผ ๋ฐฉ์๊ณผ ๊ธฐ์ ์ ํ๊ตฌํ์ฌ, ๋ ์ ์ง๋ณด์ํ๊ธฐ ์ฝ๊ณ ์ ๋ขฐํ ์ ์๋ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋๋ก ๋์ต๋๋ค.
์ฌ์ด๋ ์ดํํธ๋ ๋ฌด์์ธ๊ฐ?
ํจ์๋ ๋ก์ปฌ ์ค์ฝํ ์ธ๋ถ์ ์ํ๋ฅผ ์์ ํ๊ฑฐ๋ ๋ฐํ ๊ฐ๊ณผ ์ง์ ์ ์ธ ๊ด๋ จ์ด ์๋ ๋ฐฉ์์ผ๋ก ์ธ๋ถ ์ธ๊ณ์ ์ํธ์์ฉํ ๋ ์ฌ์ด๋ ์ดํํธ๊ฐ ์๋ค๊ณ ๋งํฉ๋๋ค. ์ผ๋ฐ์ ์ธ ์ฌ์ด๋ ์ดํํธ์ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์ ์ญ ๋ณ์ ์์
- I/O ์์ ์ํ (์: ํ์ผ ๋๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฝ๊ธฐ/์ฐ๊ธฐ)
- ๋คํธ์ํฌ ์์ฒญ
- ์์ธ ๋ฐ์
- ์ฝ์์ ๋ก๊น
- ํจ์ ์ธ์ ๋ณ๊ฒฝ
์ฌ์ด๋ ์ดํํธ๋ ์ข ์ข ํ์ํ์ง๋ง, ํต์ ๋์ง ์๋ ์ฌ์ด๋ ์ดํํธ๋ ์์ธก ๋ถ๊ฐ๋ฅํ ๋์์ผ๋ก ์ด์ด์ง๊ณ , ํ ์คํธ๋ฅผ ์ด๋ ต๊ฒ ํ๋ฉฐ, ์ฝ๋ ์ ์ง๋ณด์์ฑ์ ์ ํดํ ์ ์์ต๋๋ค. ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์๋ชป ๊ด๋ฆฌ๋ ๋คํธ์ํฌ ์์ฒญ, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ , ์ฌ์ง์ด ๊ฐ๋จํ ๋ก๊น ์กฐ์ฐจ๋ ์ฌ๋ฌ ์ง์ญ๊ณผ ์ธํ๋ผ ๊ตฌ์ฑ์ ๋ฐ๋ผ ์๋นํ ๋ค๋ฅธ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค.
์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์ถ์ ํด์ผ ํ๋๊ฐ?
์ฌ์ด๋ ์ดํํธ๋ฅผ ์ถ์ ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฌ๋ฌ ์ด์ ์ด ์์ต๋๋ค:
- ์ฝ๋ ๊ฐ๋ ์ฑ ๋ฐ ์ ์ง๋ณด์์ฑ ํฅ์: ์ฌ์ด๋ ์ดํํธ๋ฅผ ๋ช ์์ ์ผ๋ก ์๋ณํ๋ฉด ์ฝ๋๋ฅผ ๋ ์ฝ๊ฒ ์ดํดํ๊ณ ์ถ๋ก ํ ์ ์์ต๋๋ค. ๊ฐ๋ฐ์๋ ์ ์ฌ์ ์ธ ๋ฌธ์ ์์ญ์ ๋น ๋ฅด๊ฒ ํ์ ํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฌ ๋ถ๋ถ์ด ์ด๋ป๊ฒ ์ํธ์์ฉํ๋์ง ์ดํดํ ์ ์์ต๋๋ค.
- ํ ์คํธ ์ฉ์ด์ฑ ํฅ์: ์ฌ์ด๋ ์ดํํธ๋ฅผ ๋ถ๋ฆฌํจ์ผ๋ก์จ ๋ ์ง์ค์ ์ด๊ณ ์ ๋ขฐํ ์ ์๋ ๋จ์ ํ ์คํธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ๋ชจ์(Mocking) ๋ฐ ์คํ (Stubbing)์ด ๋ ์ฌ์์ ธ ์ธ๋ถ ์ข ์์ฑ์ ์ํฅ์ ๋ฐ์ง ์๊ณ ํจ์์ ํต์ฌ ๋ก์ง์ ํ ์คํธํ ์ ์์ต๋๋ค.
- ๋ ๋์ ์ค๋ฅ ์ฒ๋ฆฌ: ์ฌ์ด๋ ์ดํํธ๊ฐ ๋ฐ์ํ๋ ์์น๋ฅผ ์๋ฉด ๋ ๋ชฉํ ์งํฅ์ ์ธ ์ค๋ฅ ์ฒ๋ฆฌ ์ ๋ต์ ๊ตฌํํ ์ ์์ต๋๋ค. ์ ์ฌ์ ์ธ ์คํจ๋ฅผ ์์ธกํ๊ณ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ์ฌ ์๊ธฐ์น ์์ ์ถฉ๋์ด๋ ๋ฐ์ดํฐ ์์์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
- ์์ธก ๊ฐ๋ฅ์ฑ ์ฆ๊ฐ: ์ฌ์ด๋ ์ดํํธ๋ฅผ ์ ์ดํจ์ผ๋ก์จ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ ์์ธก ๊ฐ๋ฅํ๊ณ ๊ฒฐ์ ๋ก ์ ์ผ๋ก ๋ง๋ค ์ ์์ต๋๋ค. ์ด๋ ๋ฏธ๋ฌํ ๋ณํ๊ฐ ๊ด๋ฒ์ํ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ ์๋ ๋ณต์กํ ์์คํ ์์ ํนํ ์ค์ํฉ๋๋ค.
- ๋๋ฒ๊น ๊ฐ์ํ: ์ฌ์ด๋ ์ดํํธ๊ฐ ์ถ์ ๋๋ฉด ๋ฐ์ดํฐ์ ํ๋ฆ์ ์ถ์ ํ๊ณ ๋ฒ๊ทธ์ ๊ทผ๋ณธ ์์ธ์ ์๋ณํ๊ธฐ๊ฐ ๋ ์ฌ์์ง๋๋ค. ๋ก๊ทธ์ ๋๋ฒ๊น ๋๊ตฌ๋ฅผ ๋ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ์ฌ ๋ฌธ์ ์ ์์ธ์ ์ ํํ ์ฐพ์๋ผ ์ ์์ต๋๋ค.
ํ์ ์คํฌ๋ฆฝํธ์์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์ถ์ ํ๋ ์ ๊ทผ ๋ฐฉ์
ํ์ ์คํฌ๋ฆฝํธ์๋ ๋ด์ฅ๋ ์ดํํธ ํ์ ์ด ์์ง๋ง, ์ ์ฌํ ์ด์ ์ ์ป๊ธฐ ์ํด ์ฌ์ฉํ ์ ์๋ ๋ช ๊ฐ์ง ๊ธฐ์ ์ด ์์ต๋๋ค. ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ช ๊ฐ์ง ์ ๊ทผ ๋ฐฉ์์ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
1. ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์์น
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์์น์ ์์ฉํ๋ ๊ฒ์ ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ํฌํจํ ๋ชจ๋ ์ธ์ด์์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๊ด๋ฆฌํ๋ ๊ธฐ์ด์ ๋๋ค. ํต์ฌ ์์น์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ๋ถ๋ณ์ฑ(Immutability): ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ง์ ์์ ํ์ง ๋ง์ธ์. ๋์ , ์ํ๋ ๋ณ๊ฒฝ ์ฌํญ์ด ์ ์ฉ๋ ์ ๋ณต์ฌ๋ณธ์ ๋ง๋์ธ์. ์ด๋ ์๊ธฐ์น ์์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๋ฐฉ์งํ๊ณ ์ฝ๋๋ฅผ ๋ ์ฝ๊ฒ ์ถ๋ก ํ ์ ์๋๋ก ๋์ต๋๋ค. Immutable.js๋ Immer.js์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ถ๋ณ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
- ์์ ํจ์(Pure Functions): ๋์ผํ ์ ๋ ฅ์ ๋ํด ํญ์ ๋์ผํ ์ถ๋ ฅ์ ๋ฐํํ๊ณ ์ฌ์ด๋ ์ดํํธ๊ฐ ์๋ ํจ์๋ฅผ ์์ฑํ์ธ์. ์ด๋ฌํ ํจ์๋ ํ ์คํธํ๊ณ ์กฐํฉํ๊ธฐ๊ฐ ๋ ์ฝ์ต๋๋ค.
- ์กฐํฉ(Composition): ๋ ์์ ์์ ํจ์๋ค์ ์กฐํฉํ์ฌ ๋ ๋ณต์กํ ๋ก์ง์ ๊ตฌ์ถํ์ธ์. ์ด๋ ์ฝ๋ ์ฌ์ฌ์ฉ์ ์ด์งํ๊ณ ์ฌ์ด๋ ์ดํํธ ๋์ ์ํ์ ์ค์ ๋๋ค.
- ๊ณต์ ๊ฐ๋ณ ์ํ ํผํ๊ธฐ(Avoid Shared Mutable State): ์ฌ์ด๋ ์ดํํธ์ ๋์์ฑ ๋ฌธ์ ์ ์ฃผ๋ ์์ธ์ธ ๊ณต์ ๊ฐ๋ณ ์ํ๋ฅผ ์ต์ํํ๊ฑฐ๋ ์ ๊ฑฐํ์ธ์. ๊ณต์ ์ํ๊ฐ ๋ถ๊ฐํผํ ๊ฒฝ์ฐ, ์ ์ ํ ๋๊ธฐํ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ์ฌ ๋ณดํธํ์ธ์.
์์ : ๋ถ๋ณ์ฑ
```typescript // ๊ฐ๋ณ์ ์ ๊ทผ ๋ฐฉ์ (๋์จ) function addItemToArray(arr: number[], item: number): number[] { arr.push(item); // ์๋ณธ ๋ฐฐ์ด์ ์์ ํจ (์ฌ์ด๋ ์ดํํธ) return arr; } const myArray = [1, 2, 3]; const updatedArray = addItemToArray(myArray, 4); console.log(myArray); // ์ถ๋ ฅ: [1, 2, 3, 4] - ์๋ณธ ๋ฐฐ์ด์ด ๋ณ๊ฒฝ๋จ! console.log(updatedArray); // ์ถ๋ ฅ: [1, 2, 3, 4] // ๋ถ๋ณ์ ์ ๊ทผ ๋ฐฉ์ (์ข์) function addItemToArrayImmutable(arr: number[], item: number): number[] { return [...arr, item]; // ์ ๋ฐฐ์ด์ ์์ฑํจ (์ฌ์ด๋ ์ดํํธ ์์) } const myArray2 = [1, 2, 3]; const updatedArray2 = addItemToArrayImmutable(myArray2, 4); console.log(myArray2); // ์ถ๋ ฅ: [1, 2, 3] - ์๋ณธ ๋ฐฐ์ด์ ๋ณ๊ฒฝ๋์ง ์์ console.log(updatedArray2); // ์ถ๋ ฅ: [1, 2, 3, 4] ```2. `Result` ๋๋ `Either` ํ์ ์ ์ด์ฉํ ๋ช ์์ ์ค๋ฅ ์ฒ๋ฆฌ
try-catch ๋ธ๋ก๊ณผ ๊ฐ์ ์ ํต์ ์ธ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฉ์ปค๋์ฆ์ ์ ์ฌ์ ์ธ ์์ธ๋ฅผ ์ถ์ ํ๊ณ ์ผ๊ด๋๊ฒ ์ฒ๋ฆฌํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. `Result` ๋๋ `Either` ํ์ ์ ์ฌ์ฉํ๋ฉด ์คํจ ๊ฐ๋ฅ์ฑ์ ํจ์์ ๋ฐํ ํ์ ์ ์ผ๋ถ๋ก ๋ช ์์ ์ผ๋ก ํํํ ์ ์์ต๋๋ค.
A `Result` ํ์ ์ ์ผ๋ฐ์ ์ผ๋ก `Success`์ `Failure` ๋ ๊ฐ์ง ๊ฐ๋ฅํ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง๋๋ค. `Either` ํ์ ์ `Result`์ ๋ ์ผ๋ฐ์ ์ธ ๋ฒ์ ์ผ๋ก, ๋ ๊ฐ์ง ๊ตฌ๋ณ๋๋ ๊ฒฐ๊ณผ ํ์ (์ข ์ข `Left`์ `Right`๋ก ๋ถ๋ฆผ)์ ๋ํ๋ผ ์ ์์ต๋๋ค.
์์ : `Result` ํ์
```typescript interface Success์ด ์ ๊ทผ ๋ฐฉ์์ ํธ์ถ์๊ฐ ์ ์ฌ์ ์ธ ์คํจ ์ฌ๋ก๋ฅผ ๋ช ์์ ์ผ๋ก ์ฒ๋ฆฌํ๋๋ก ๊ฐ์ ํ์ฌ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๋ ๊ฒฌ๊ณ ํ๊ณ ์์ธก ๊ฐ๋ฅํ๊ฒ ๋ง๋ญ๋๋ค.
3. ์์กด์ฑ ์ฃผ์ (Dependency Injection)
์์กด์ฑ ์ฃผ์ (DI)์ ๋ด๋ถ์์ ์์กด์ฑ์ ์์ฑํ๋ ๋์ ์ธ๋ถ์์ ์ ๊ณตํจ์ผ๋ก์จ ์ปดํฌ๋ํธ ๊ฐ์ ๊ฒฐํฉ์ ๋ฎ์ถ๋ ๋์์ธ ํจํด์ ๋๋ค. ์ด๋ ํ ์คํธ ์ค์ ์์กด์ฑ์ ์ฝ๊ฒ ๋ชจ์(mock)ํ๊ณ ์คํ (stub)ํ ์ ์๊ฒ ํด์ฃผ๋ฏ๋ก ์ฌ์ด๋ ์ดํํธ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค.
์ฌ์ด๋ ์ดํํธ๋ฅผ ์ํํ๋ ์์กด์ฑ(์: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ, API ํด๋ผ์ด์ธํธ)์ ์ฃผ์ ํจ์ผ๋ก์จ, ํ ์คํธ์์ ์ด๋ฅผ ๋ชจ์ ๊ตฌํ์ผ๋ก ๋์ฒดํ์ฌ ํ ์คํธ ๋์ ์ปดํฌ๋ํธ๋ฅผ ๊ฒฉ๋ฆฌํ๊ณ ์ค์ ์ฌ์ด๋ ์ดํํธ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
์์ : ์์กด์ฑ ์ฃผ์
```typescript interface Logger { log(message: string): void; } class ConsoleLogger implements Logger { log(message: string): void { console.log(message); // ์ฌ์ด๋ ์ดํํธ: ์ฝ์์ ๋ก๊น } } class MyService { private logger: Logger; constructor(logger: Logger) { this.logger = logger; } doSomething(data: string): void { this.logger.log(`Processing data: ${data}`); // ... ์ผ๋ถ ์์ ์ํ ... } } // ํ๋ก๋์ ์ฝ๋ const logger = new ConsoleLogger(); const service = new MyService(logger); service.doSomething("Important data"); // ํ ์คํธ ์ฝ๋ (๋ชจ์ ๋ก๊ฑฐ ์ฌ์ฉ) class MockLogger implements Logger { log(message: string): void { // ์๋ฌด๊ฒ๋ ํ์ง ์์ (๋๋ ๋จ์ธ์ ์ํด ๋ฉ์์ง ๊ธฐ๋ก) } } const mockLogger = new MockLogger(); const testService = new MyService(mockLogger); testService.doSomething("Test data"); // ์ฝ์ ์ถ๋ ฅ ์์ ```์ด ์์ ์์ `MyService`๋ `Logger` ์ธํฐํ์ด์ค์ ์์กดํฉ๋๋ค. ํ๋ก๋์ ์์๋ ์ฝ์์ ๋ก๊น ํ๋ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์ํํ๋ `ConsoleLogger`๊ฐ ์ฌ์ฉ๋ฉ๋๋ค. ํ ์คํธ์์๋ ์๋ฌด๋ฐ ์ฌ์ด๋ ์ดํํธ๋ ์ํํ์ง ์๋ `MockLogger`๊ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ์ค์ ๋ก ์ฝ์์ ๋ก๊น ํ์ง ์๊ณ `MyService`์ ๋ก์ง์ ํ ์คํธํ ์ ์์ต๋๋ค.
4. ์ดํํธ ๊ด๋ฆฌ๋ฅผ ์ํ ๋ชจ๋๋ (Task, IO, Reader)
๋ชจ๋๋๋ ํต์ ๋ ๋ฐฉ์์ผ๋ก ์ฌ์ด๋ ์ดํํธ๋ฅผ ๊ด๋ฆฌํ๊ณ ์กฐํฉํ๋ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ํ์ ์คํฌ๋ฆฝํธ๋ ํ์ค์ผ์ฒ๋ผ ๋ค์ดํฐ๋ธ ๋ชจ๋๋๋ฅผ ๊ฐ์ง๊ณ ์์ง ์์ง๋ง, ํด๋์ค๋ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋๋ ํจํด์ ๊ตฌํํ ์ ์์ต๋๋ค.
์ดํํธ ๊ด๋ฆฌ์ ์ฌ์ฉ๋๋ ์ผ๋ฐ์ ์ธ ๋ชจ๋๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- Task/Future: ๊ถ๊ทน์ ์ผ๋ก ๊ฐ ๋๋ ์ค๋ฅ๋ฅผ ์์ฑํ ๋น๋๊ธฐ ๊ณ์ฐ์ ๋ํ๋ ๋๋ค. ์ด๋ ๋คํธ์ํฌ ์์ฒญ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ์ ๊ฐ์ ๋น๋๊ธฐ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
- IO: I/O ์์ ์ ์ํํ๋ ๊ณ์ฐ์ ๋ํ๋ ๋๋ค. ์ด๋ฅผ ํตํด ์ฌ์ด๋ ์ดํํธ๋ฅผ ์บก์ํํ๊ณ ์คํ ์์ ์ ์ ์ดํ ์ ์์ต๋๋ค.
- Reader: ์ธ๋ถ ํ๊ฒฝ์ ์์กดํ๋ ๊ณ์ฐ์ ๋ํ๋ ๋๋ค. ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฌ ๋ถ๋ถ์์ ํ์ํ ๊ตฌ์ฑ์ด๋ ์์กด์ฑ์ ๊ด๋ฆฌํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
์์ : ๋น๋๊ธฐ ์ฌ์ด๋ ์ดํํธ์ `Task` ์ฌ์ฉํ๊ธฐ
```typescript // ๋จ์ํ๋ Task ๊ตฌํ (์์ฐ์ฉ) class Task์ด๊ฒ์ ๋จ์ํ๋ `Task` ๊ตฌํ์ด์ง๋ง, ๋ชจ๋๋๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์บก์ํํ๊ณ ์ ์ดํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. fp-ts๋ remeda์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ํ ๋ชจ๋๋ ๋ฐ ๊ธฐํ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ๊ตฌ์กฐ์ ๋ ๊ฒฌ๊ณ ํ๊ณ ๊ธฐ๋ฅ์ด ํ๋ถํ ๊ตฌํ์ ์ ๊ณตํฉ๋๋ค.
5. ๋ฆฐํฐ ๋ฐ ์ ์ ๋ถ์ ๋๊ตฌ
๋ฆฐํฐ์ ์ ์ ๋ถ์ ๋๊ตฌ๋ ์ฝ๋ฉ ํ์ค์ ๊ฐ์ ํ๊ณ ์ฝ๋์์ ์ ์ฌ์ ์ธ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์๋ณํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. ESLint์ `eslint-plugin-functional` ๊ฐ์ ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ฉด ๊ฐ๋ณ ๋ฐ์ดํฐ ๋ฐ ๋น์์ ํจ์์ ๊ฐ์ ์ผ๋ฐ์ ์ธ ์ํฐํจํด์ ์๋ณํ๊ณ ๋ฐฉ์งํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์์น์ ๊ฐ์ ํ๋๋ก ๋ฆฐํฐ๋ฅผ ๊ตฌ์ฑํจ์ผ๋ก์จ, ์ฌ์ด๋ ์ดํํธ๊ฐ ์ฝ๋๋ฒ ์ด์ค์ ์ค๋ฉฐ๋๋ ๊ฒ์ ์ฌ์ ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
์์ : ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ํ ESLint ๊ตฌ์ฑ
ํ์ํ ํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค:
```bash npm install --save-dev eslint eslint-plugin-functional ```๋ค์ ๋ด์ฉ์ผ๋ก `.eslintrc.js` ํ์ผ์ ์์ฑํฉ๋๋ค:
```javascript module.exports = { extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:functional/recommended', ], parser: '@typescript-eslint/parser', plugins: ['@typescript-eslint', 'functional'], rules: { // ํ์์ ๋ฐ๋ผ ๊ท์น ์ฌ์ฉ์ ์ ์ 'functional/no-let': 'warn', 'functional/immutable-data': 'warn', 'functional/no-expression-statement': 'off', // ๋๋ฒ๊น ์ ์ํด console.log ํ์ฉ }, }; ```์ด ๊ตฌ์ฑ์ `eslint-plugin-functional` ํ๋ฌ๊ทธ์ธ์ ํ์ฑํํ๊ณ `let`(๊ฐ๋ณ ๋ณ์) ๋ฐ ๊ฐ๋ณ ๋ฐ์ดํฐ์ ์ฌ์ฉ์ ๋ํด ๊ฒฝ๊ณ ํ๋๋ก ์ค์ ํฉ๋๋ค. ๋น์ ์ ํน์ ์๊ตฌ์ ๋ง๊ฒ ๊ท์น์ ์ฌ์ฉ์ ์ ์ํ ์ ์์ต๋๋ค.
๋ค์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ ๊ฑธ์น ์ค์ ์์
์ด๋ฌํ ๊ธฐ์ ์ ์ ์ฉ์ ๊ฐ๋ฐ ์ค์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ๋ช ๊ฐ์ง ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
1. ์น ์ ํ๋ฆฌ์ผ์ด์ (React, Angular, Vue.js)
- ์ํ ๊ด๋ฆฌ: Redux, Zustand ๋๋ Recoil๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์์ธก ๊ฐ๋ฅํ๊ณ ๋ถ๋ณ์ ์ธ ๋ฐฉ์์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ํ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. ์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ํ ๋ณ๊ฒฝ์ ์ถ์ ํ๊ณ ์๋ํ์ง ์์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๋ฐฉ์งํ๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค.
- ์ดํํธ ์ฒ๋ฆฌ: Redux Thunk, Redux Saga ๋๋ RxJS์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ API ํธ์ถ๊ณผ ๊ฐ์ ๋น๋๊ธฐ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. ์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์กฐํฉํ๊ณ ์ ์ดํ๊ธฐ ์ํ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ์ปดํฌ๋ํธ ์ค๊ณ: props์ state๋ฅผ ๊ธฐ๋ฐ์ผ๋ก UI๋ฅผ ๋ ๋๋งํ๋ ์์ ํจ์๋ก ์ปดํฌ๋ํธ๋ฅผ ์ค๊ณํฉ๋๋ค. ์ปดํฌ๋ํธ ๋ด์์ props๋ state๋ฅผ ์ง์ ์์ ํ์ง ๋ง์ธ์.
2. Node.js ๋ฐฑ์๋ ์ ํ๋ฆฌ์ผ์ด์
- ์์กด์ฑ ์ฃผ์ : InversifyJS๋ TypeDI์ ๊ฐ์ DI ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ์ฌ ์์กด์ฑ์ ๊ด๋ฆฌํ๊ณ ํ ์คํธ๋ฅผ ์ฉ์ดํ๊ฒ ํฉ๋๋ค.
- ์ค๋ฅ ์ฒ๋ฆฌ: `Result` ๋๋ `Either` ํ์ ์ ์ฌ์ฉํ์ฌ API ์๋ํฌ์ธํธ ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์์ ๋ฐ์ํ ์ ์๋ ์ค๋ฅ๋ฅผ ๋ช ์์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
- ๋ก๊น : Winston์ด๋ Pino์ ๊ฐ์ ๊ตฌ์กฐํ๋ ๋ก๊น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ฒคํธ ๋ฐ ์ค๋ฅ์ ๋ํ ์์ธ ์ ๋ณด๋ฅผ ์บก์ฒํฉ๋๋ค. ๋ค์ํ ํ๊ฒฝ์ ๋ง๊ฒ ๋ก๊น ์์ค์ ์ ์ ํ๊ฒ ๊ตฌ์ฑํฉ๋๋ค.
3. ์๋ฒ๋ฆฌ์ค ํจ์ (AWS Lambda, Azure Functions, Google Cloud Functions)
- ์ํ ๋น์ ์ฅ ํจ์(Stateless Functions): ํจ์๋ฅผ ์ํ ๋น์ ์ฅ(stateless) ๋ฐ ๋ฉฑ๋ฑ์ฑ(idempotent)์ ๊ฐ๋๋ก ์ค๊ณํฉ๋๋ค. ํธ์ถ ์ฌ์ด์ ์ด๋ค ์ํ๋ ์ ์ฅํ์ง ๋ง์ธ์.
- ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ: ์๊ธฐ์น ์์ ์ค๋ฅ์ ๋ณด์ ์ทจ์ฝ์ ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ์๊ฒฉํ๊ฒ ๊ฒ์ฆํฉ๋๋ค.
- ์ค๋ฅ ์ฒ๋ฆฌ: ์คํจ๋ฅผ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ๊ณ ํจ์ ์ถฉ๋์ ๋ฐฉ์งํ๊ธฐ ์ํด ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํฉ๋๋ค. ์ค๋ฅ ๋ชจ๋ํฐ๋ง ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฅ๋ฅผ ์ถ์ ํ๊ณ ์ง๋จํฉ๋๋ค.
์ฌ์ด๋ ์ดํํธ ์ถ์ ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
ํ์ ์คํฌ๋ฆฝํธ์์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์ถ์ ํ ๋ ๋ช ์ฌํด์ผ ํ ๋ช ๊ฐ์ง ๋ชจ๋ฒ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ๋ช ์์ ์ผ๋ก ํํํ๊ธฐ: ์ฝ๋์ ๋ชจ๋ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๋ช ํํ๊ฒ ์๋ณํ๊ณ ๋ฌธ์ํํ์ธ์. ๋ช ๋ช ๊ท์น์ด๋ ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ฌ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์ํํ๋ ํจ์๋ฅผ ํ์ํ์ธ์.
- ์ฌ์ด๋ ์ดํํธ ๋ถ๋ฆฌํ๊ธฐ: ์ฌ์ด๋ ์ดํํธ๋ฅผ ์ต๋ํ ๊ฒฉ๋ฆฌํ๋ ค๊ณ ๋ ธ๋ ฅํ์ธ์. ์ฌ์ด๋ ์ดํํธ๊ฐ ๋ฐ์ํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ ๋ก์ง๊ณผ ๋ถ๋ฆฌํ์ฌ ์ ์งํ์ธ์.
- ์ฌ์ด๋ ์ดํํธ ์ต์ํํ๊ธฐ: ์ฌ์ด๋ ์ดํํธ์ ์์ ๋ฒ์๋ฅผ ๊ฐ๋ฅํ ํ ์ค์ด์ธ์. ์ธ๋ถ ์ํ์ ๋ํ ์์กด์ฑ์ ์ต์ํํ๋๋ก ์ฝ๋๋ฅผ ๋ฆฌํฉํ ๋งํ์ธ์.
- ์ฒ ์ ํ๊ฒ ํ ์คํธํ๊ธฐ: ์ฌ์ด๋ ์ดํํธ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌ๋๋์ง ํ์ธํ๊ธฐ ์ํด ํฌ๊ด์ ์ธ ํ ์คํธ๋ฅผ ์์ฑํ์ธ์. ํ ์คํธ ์ค์ ์ปดํฌ๋ํธ๋ฅผ ๊ฒฉ๋ฆฌํ๊ธฐ ์ํด ๋ชจ์(mocking) ๋ฐ ์คํ (stubbing)์ ์ฌ์ฉํ์ธ์.
- ํ์ ์์คํ ํ์ฉํ๊ธฐ: ํ์ ์คํฌ๋ฆฝํธ์ ํ์ ์์คํ ์ ํ์ฉํ์ฌ ์ ์ฝ ์กฐ๊ฑด์ ๊ฐ์ ํ๊ณ ์๋ํ์ง ์์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๋ฐฉ์งํ์ธ์. `ReadonlyArray` ๋๋ `Readonly`์ ๊ฐ์ ํ์ ์ ์ฌ์ฉํ์ฌ ๋ถ๋ณ์ฑ์ ๊ฐ์ ํ์ธ์.
- ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์์น ์ฑํํ๊ธฐ: ๋ ์์ธก ๊ฐ๋ฅํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํด ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์์น์ ์์ฉํ์ธ์.
๊ฒฐ๋ก
ํ์ ์คํฌ๋ฆฝํธ์๋ ๋ค์ดํฐ๋ธ ์ดํํธ ํ์ ์ด ์์ง๋ง, ์ด ๊ธ์์ ๋ ผ์๋ ๊ธฐ์ ๋ค์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๊ด๋ฆฌํ๊ณ ์ถ์ ํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์์น์ ์์ฉํ๊ณ , ๋ช ์์ ์ธ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉฐ, ์์กด์ฑ ์ฃผ์ ์ ์ฑํํ๊ณ , ๋ชจ๋๋๋ฅผ ํ์ฉํจ์ผ๋ก์จ ๋ ๊ฒฌ๊ณ ํ๊ณ , ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ฐ๋ฉฐ, ์์ธก ๊ฐ๋ฅํ ํ์ ์คํฌ๋ฆฝํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ฑํ ์ ์์ต๋๋ค. ํ๋ก์ ํธ์ ์๊ตฌ์ฌํญ๊ณผ ์ฝ๋ฉ ์คํ์ผ์ ๊ฐ์ฅ ์ ํฉํ ์ ๊ทผ ๋ฐฉ์์ ์ ํํ๊ณ , ์ฝ๋ ํ์ง๊ณผ ํ ์คํธ ์ฉ์ด์ฑ์ ํฅ์์ํค๊ธฐ ์ํด ํญ์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์ต์ํํ๊ณ ๊ฒฉ๋ฆฌํ๋ ค๊ณ ๋ ธ๋ ฅํด์ผ ํฉ๋๋ค. ํ์ ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์ ์งํํ๋ ํ๊ฒฝ์ ์ ์ํ๊ณ ํ๋ก์ ํธ์ ์ฅ๊ธฐ์ ์ธ ๊ฑด๊ฐ์ ๋ณด์ฅํ๊ธฐ ์ํด ์ ๋ต์ ์ง์์ ์ผ๋ก ํ๊ฐํ๊ณ ๊ฐ์ ํ์ธ์. ํ์ ์คํฌ๋ฆฝํธ ์ํ๊ณ๊ฐ ์ฑ์ํด์ง์ ๋ฐ๋ผ, ์ฌ์ด๋ ์ดํํธ ๊ด๋ฆฌ๋ฅผ ์ํ ๊ธฐ์ ๊ณผ ๋๊ตฌ์ ์ถ๊ฐ์ ์ธ ๋ฐ์ ์ ๊ธฐ๋ํ ์ ์์ผ๋ฉฐ, ์ด๋ ์ ๋ขฐํ ์ ์๊ณ ํ์ฅ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๊ฒ์ ๋์ฑ ์ฝ๊ฒ ๋ง๋ค ๊ฒ์ ๋๋ค.